import random

import datetime
from django.shortcuts import render

# Create your views here.

# POST /users/
from django_redis import get_redis_connection
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.generics import CreateAPIView
from rest_framework.mixins import CreateModelMixin, UpdateModelMixin
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet
from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.views import ObtainJSONWebToken, jwt_response_payload_handler

from users import constants
from users.serializer import UserSerializer, UserAddressSerializer, AddressTitleSerializer


class UserView(CreateAPIView):
    serializer_class = UserSerializer

    # def post(self, request):
    #     """
    #     注册用户信息的保存:
    #     1. 接收参数并进行校验(参数完整性，手机号是否正确，手机号是否存在，是否同意协议，两次密码是否一致，短信验证码是否正确)
    #     2. 创建用户并保存到数据库
    #     3. 返回应答，注册成功
    #     """
    #     # 1. 接收参数并进行校验(参数完整性，手机号是否正确，手机号是否存在，是否同意协议，两次密码是否一致，短信验证码是否正确)
    #     serializer = self.get_serializer(data=request.data)
    #     serializer.is_valid(raise_exception=True)
    #
    #     # 2. 创建用户并保存到数据库(create)
    #     serializer.save()
    #
    #     # 3. 返回应答，注册成功
    #     return Response(serializer.data, status=status.HTTP_201_CREATED)



# GET /sms_codes/(?P<mobile>1[3-9]\d{9})/
class SMSCodeView(APIView):
    def get(self, request, mobile):
        """
        获取短信验证码:
        1. 随机生成6位数字作为短信验证码
        2. 在redis中存储短信验证码内容，以`mobile`为key，以短信验证码的内容为value
        3. 使用云通讯给`mobile`发送短信验证码
        4. 返回应答，发送短信成功
        """
        # 获取redis链接
        redis_conn = get_redis_connection('verify_codes')
        # 判断60s之内是否给`mobile`发送过短信
        send_flag = redis_conn.get('send_flag_%s' % mobile) # None

        if send_flag:
            return Response({'message': '发送短信过于频繁'}, status=status.HTTP_400_BAD_REQUEST)

        # 1. 随机生成6位数字作为短信验证码
        sms_code = '%06d' % random.randint(0, 999999) # 000010
        print('短信验证码为: %s' % sms_code)

        # 2. 在redis中存储短信验证码内容，以`mobile`为key，以短信验证码的内容为value
        # redis管道：可以向管道中添加多个redis命令，然后一次性执行
        # 创建redis管道对象
        pl = redis_conn.pipeline()

        # redis_conn.set('<key>', '<value>', '<expries>')
        # redis_conn.setex('<key>', '<expires>', '<value>')
        # 向redis管道中添加命令
        pl.setex('sms_%s' % mobile, constants.SMS_CODES_REDIS_EXPIRES, sms_code)
        # 保存给`mobile`手机号发送短信标记
        pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)

        # 一次性执行管道中的命令
        pl.execute()

        # 3. 使用云通讯给`mobile`发送短信验证码
        expires = constants.SMS_CODES_REDIS_EXPIRES // 60

        # 发出发送短信的任务消息
        # from celery_tasks.sms.tasks import send_sms_code
        # send_sms_code.delay(mobile, sms_code, expires)

        # 4. 返回应答，发送短信成功
        return Response({'message': 'OK'})


# POST /authorizations/
# class UserAuthorizeView(ObtainJSONWebToken):
#     def post(self, request, *args, **kwargs):
#         serializer = self.get_serializer(data=request.data)
#
#         if serializer.is_valid():
#             # 登录成功
#             user = serializer.object.get('user') or request.user
#             token = serializer.object.get('token')
#             response_data = jwt_response_payload_handler(token, user, request)
#             response = Response(response_data)
#             if api_settings.JWT_AUTH_COOKIE:
#                 expiration = (datetime.utcnow() +
#                               api_settings.JWT_EXPIRATION_DELTA)
#                 response.set_cookie(api_settings.JWT_AUTH_COOKIE,
#                                     token,
#                                     expires=expiration,
#                                     httponly=True)
#
#             return response

        # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)




# POST /addresses/
class AddressViewSet(CreateModelMixin, UpdateModelMixin, GenericViewSet):
    serializer_class = UserAddressSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        return self.request.user.addresses.filter(is_deleted=False)

    # GET /addresses/
    def list(self, request, *args, **kwargs):
        """
        用户地址列表数据
        """
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        user = request.user
        return Response({
            'user_id': user.id,
            'default_address_id': user.default_address_id,
            # 'limit': constants.USER_ADDRESS_COUNTS_LIMIT,
            'addresses': serializer.data,
        })

    # def create(self, request, *args, **kwargs):
    #     """
    #     地址的新增:
    #     0. 判断用户的地址数量是否超过上限
    #     1. 获取参数并进行校验
    #     2. 创建并保存用户的地址信息
    #     3. 返回应答
    #     """
        # 0. 判断用户的地址数量是否超过上限
        # user = request.user
        # 获取登录用户地址数量
        # count = user.addresses.filter(is_deleted=False).count()

        # if count > constants.USER_ADDRESS_COUNTS_LIMIT:
        #     return Response({'message': '地址数量超过上限'}, status=status.HTTP_400_BAD_REQUEST)

        # return super().create(request)
        #
        # # 1. 获取参数并进行校验
        # serializer = self.get_serializer(data=request.data)
        # serializer.is_valid(raise_exception=True)
        #
        # # 2. 创建并保存用户的地址信息(create)
        # serializer.save()
        #
        # # 3. 返回应答
        # return Response(serializer.data, status=status.HTTP_201_CREATED)

    # delete /addresses/<pk>/
    def destroy(self, request, *args, **kwargs):
        """
        处理删除
        """
        address = self.get_object()

        # 进行逻辑删除
        address.is_deleted = True
        address.save()

        return Response(status=status.HTTP_204_NO_CONTENT)

    # put /addresses/pk/status/
    @action(methods=['put'], detail=True)
    def status(self, request, pk=None):
        """
        设置默认地址
        """
        # 从用户的地址中根据pk获取对应地址
        address = self.get_object()
        # 将当前地址设置为用户的默认地址
        request.user.default_address = address
        request.user.save()
        return Response({'message': 'OK'}, status=status.HTTP_200_OK)

